# Copyright (c) 2020 Presto Labs Pte. Ltd.
# Author: jingyuan

import os
import json
from datetime import datetime, timedelta

from absl import app, flags

FLAGS = flags.FLAGS


def get_recipe(mea, recipe):
  if recipe:
    return recipe
  return "realtime_light_bbo"


def generate_sim_configs(archive_from_dt, archive_to_dt):
  meas = flags.FLAGS.mea.split(',')
  recipes = []
  for mea in meas:
    if ':' in mea:
      recipes.append(get_recipe(*mea.split(':')))
    else:
      recipes.append(get_recipe(mea, ''))
  meas = [m.split(':')[0] for m in meas]
  reserves = [float(r) for r in flags.FLAGS.reserves.split(',')]
  if "," in flags.FLAGS.product:
    products = flags.FLAGS.product.split(',')
  else:
    products = [flags.FLAGS.product] * 2 
  start_date = datetime.strptime(archive_from_dt, "%Y%m%dT%H%M%S")
  start_date -= timedelta(seconds=flags.FLAGS.window_period_seconds)
  TIMESTAMP_FORMAT = '%Y%m%dT%H%M%S'

  with open(flags.FLAGS.sim_setting_json) as f:
    settings_json = json.load(f)
    latency = max(
        settings_json.get(f'{mea}', {}).get("latency_sec", 0)
        for mea in meas)

  combined = {
      "strategy": {
          "strategy_name": "basis_exchange_{name}_btc_usd_30m",
          "strategy_group": "basis_exchange"
      }
  }
  combined['feed'] = {
      "common": {
          "type": "FEED_SYSTEM_TYPE_ARCHIVE",
          "archive": {
              "machine": "feed-05.ap-northeast-1.aws",
              "archive_type": "FASTFEED",
              "interval": {
                  "start": start_date.strftime(TIMESTAMP_FORMAT)
              }
          }
      },
      "exchanges": {
          ".".join(mea.split(".")[:2] + [product]): {
              "mea": mea,
              "products": {
                  "norms": [product]
              },
              "recipe": recipe
          } for mea, product, recipe in zip(meas, products, recipes)
      }
  }
  if archive_to_dt:
    combined['feed']['common']['archive']['interval']['end'] = archive_to_dt
  else:
    combined['feed']['common']['archive']['interval']['duration'] = f"PT{flags.FLAGS.hours}{flags.FLAGS.window_period_seconds}S"
  combined['order'] = {
      "common": {
          "type": "ORDER_SYSTEM_TYPE_SIM_OG",
          "sim_config": {
              "start_timestamp": start_date.timestamp() * 1e9
          }
      },
      "exchanges": {
          ".".join(mea.split(".")[:2] + [product]): {
              "mea": mea,
              "products": {
                  "norms": [product]
              },
              "sim_config": {
                  "latency_sec": latency,
                  "is_snapshot": settings_json.get(f'{mea}').get("is_snapshot", False),
                  "reserve_symbols": [product],
                  "reserve_positions": [reserve],
                  # "latency_file_path":
                  #     "/remote/iosg/home/public/latency/",
                  # "latency_window_sec":
                  #     20,
                  # "product_configs": {
                  #     flags.FLAGS.product: {
                  #         'use_order_latency_model': True
                  #     }
                  # }
              }
          } for mea, product, reserve in zip(meas, products, reserves)
      }
  }
  return combined


def generate_and_output_configs(output_path, archive_from_dt=None, archive_to_dt=None, is_sim=True):
  assert is_sim, "not live"
  if is_sim:
    configs = generate_sim_configs(archive_from_dt, archive_to_dt)
  # else:
  # configs = generate_live_configs(config_path)
  dir_path = os.path.dirname(output_path)
  if dir_path and not os.path.exists(dir_path):
    os.makedirs(dir_path)
  with open(output_path, 'w') as fo:
    json.dump(configs, fo, indent=2)


def main(argv):

  assert FLAGS.output_path
  generate_and_output_configs(
      FLAGS.output_path,
      FLAGS.archive_from_dt,
      FLAGS.archive_to_dt,
      FLAGS.is_sim)


if __name__ == '__main__':
  flags.DEFINE_integer('window_period_seconds', 0, "window period")
  flags.DEFINE_string('archive_from_dt', '', '')
  flags.DEFINE_string('archive_to_dt', '' , '')
  flags.DEFINE_string('product', 'BTC-USD.QUARTER', '')
  flags.DEFINE_string('mea', 'Futures.Huobi.v1,Futures.Okex.v3:snapshot', '')
  flags.DEFINE_string('reserves', '', 'reserves seperated by comma')
  flags.DEFINE_string('output_path', '', '')
  flags.DEFINE_string('hours', None, '')
  flags.DEFINE_boolean('is_sim', True, '')
  flags.DEFINE_string('sim_setting_json', 'data/coin2/sim/sim_setting.json',
                      'data/coin2/sim/sim_setting.json')
  app.run(main)
